package cn.nju.zyy.share.criticalsection;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

// Synchronize the entire method:
class ExplicitPairManager1 extends PairManager {
	private Lock lock = new ReentrantLock();
	
	@Override
	public void increment() {
		lock.lock();
		try {
			p.incrementX();
			p.incrementY();
			store(getPair());
		} finally {
			lock.unlock();
		}
	}

	@Override
	public Pair getPair() {
		lock.lock();
		try {
			return new Pair(p.getX(), p.getY());
		} finally {
			lock.unlock();
		}
	}
	
}

// Use a critical section:
class ExplicitPairManager2 extends PairManager {
	private Lock lock = new ReentrantLock();
	
	@Override
	public void increment() {
		Pair temp;
		lock.lock();
		try {
			p.incrementX();
			p.incrementY();
			temp = getPair();
		} finally {
			lock.unlock();
		}
		store(temp);
	}

	@Override
	public Pair getPair() {
		lock.lock();
		try {
			return new Pair(p.getX(), p.getY());
		} finally {
			lock.unlock();
		}
	}
	
}

public class ExplicitCriticalSection {

	public static void main(String[] args) {
		PairManager pm1 = new ExplicitPairManager1(),
				pm2 = new ExplicitPairManager2();
		CriticalSection.testApproaches(pm1, pm2);
	}

}
